#include "dialogprogram.h"
#include "ui_dialogprogram.h"
#include "appconst.h"
#include "TStringUtil.h"
#include <QStyledItemDelegate>
#include "excelfile.h"
#include "appconst.h"
#include <QFileDialog>
#include <QMessageBox>


DialogProgram::DialogProgram(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogProgram)
{
    ui->setupUi(this);

    fillNumCombo();
}

DialogProgram::~DialogProgram()
{
    delete ui;
}

void DialogProgram::setFreqList(tv::FrequenceList& freqList)
{
    m_freqList = freqList;

    fillFreqCombo();
}

void DialogProgram::setProgramList(tv::ProgramList& programList)
{
    m_programList = programList;

    refreshTable();
}

tv::ProgramList& DialogProgram::getProgramList()
{
    return m_programList;
}



void DialogProgram::on_pushButtonAdd_clicked()
{
    QString num = ui->comboBoxNum->currentText();
    QString name = ui->lineEditName->text();
    QString memo = ui->textEditMemo->toPlainText();
    QString url = ui->lineEditUrl->text();
    QString freqNum = ui->comboBoxFreqNum->currentText();
    QString freqName = ui->comboBoxFreqName->currentText();

    if (num.length() != 4)
    {
        QMessageBox::warning(this, "验证失败.", "序号取值必须在[0001,9999]之间.");
        return;
    }

    if (name.isEmpty())
    {
        QMessageBox::warning(this, "验证失败.", "名称必填.");
        return;
    }

    if (m_programList.contains(num.toStdString()))
    {
        QMessageBox::warning(this, "验证失败.", "序号已经存在.");
        return;
    }

    tv::Program program;
    program.num = num.toStdString();
    program.name = name.toStdString();
    program.memo = memo.toStdString();
    program.freqNum = freqNum.toStdString();
    program.freqName = freqName.toStdString();
    program.url = url.toStdString();

    m_programList.push_back(program);
    appendProgram(program);
}

void DialogProgram::on_pushButtonDelete_clicked()
{
    int row = ui->tableWidget->currentRow();
    if (row < 0 || row >= ui->tableWidget->rowCount())
    {
        return;
    }

    m_programList.remove(row);
    ui->tableWidget->removeRow(row);
}

void DialogProgram::on_pushButtonEdit_clicked()
{
    int row = ui->tableWidget->currentRow();
    updateProgram(row);
}

void DialogProgram::on_pushButtonImport_clicked()
{
    QFileDialog fileDialog(this);
    fileDialog.setFileMode(QFileDialog::ExistingFile);
    if (fileDialog.exec() != QDialog::Accepted)
    {
        return;
    }

    QStringList fileList = fileDialog.selectedFiles();
    if (fileList.empty())
    {
        return;
    }

    std::string filepath = fileList[0].toStdString();
    ExcelFile::load(filepath, m_programList);

    refreshTable();
}

void DialogProgram::on_pushButtonExport_clicked()
{
	QString dir = AppConst::getQAppDir();
    QString filename = QFileDialog::getSaveFileName(this, tr("Save File"), dir,
        tr("Excel file (*.xlsx)"));

    std::string filepath = filename.toStdString();
    ExcelFile::save(m_programList, filepath);
}

void DialogProgram::setProgram(int row, const tv::Program& program)
{
    int col = 0;

    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(program.num.c_str());

        Qt::ItemFlags flags = item->flags();
        flags &= ~Qt::ItemIsEditable;
        item->setFlags(flags);

        item->setData(kNumRole, program.num.c_str());

        ui->tableWidget->setItem(row, col ++, item);
    }

    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(program.name.c_str());
        Qt::ItemFlags flags = item->flags();
        flags &= ~Qt::ItemIsEditable;
        item->setFlags(flags);
        ui->tableWidget->setItem(row, col ++, item);
    }


    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(program.freqNum.c_str());
        Qt::ItemFlags flags = item->flags();
        flags &= ~Qt::ItemIsEditable;
        item->setFlags(flags);
        ui->tableWidget->setItem(row, col ++, item);
    }

    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(program.freqName.c_str());
        Qt::ItemFlags flags = item->flags();
        flags &= ~Qt::ItemIsEditable;
        item->setFlags(flags);
        ui->tableWidget->setItem(row, col ++, item);
    }

    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(program.url.c_str());
        Qt::ItemFlags flags = item->flags();
        flags &= ~Qt::ItemIsEditable;
        item->setFlags(flags);
        ui->tableWidget->setItem(row, col ++, item);
    }

    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(program.memo.c_str());
        Qt::ItemFlags flags = item->flags();
        flags &= ~Qt::ItemIsEditable;
        item->setFlags(flags);
        ui->tableWidget->setItem(row, col ++, item);
    }
}

void DialogProgram::fillNumCombo()
{
    QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();
    ui->comboBoxNum->setItemDelegate(itemDelegate);
    ui->comboBoxNum->setStyleSheet("QComboBox QAbstractItemView::item {min-height: 28px;}");

    ui->comboBoxNum->setValidator(new QIntValidator());

    for (int i = 1; i <= AppConst::MAX_PROGRAM_NUM; ++ i)
    {
        std::string num = comn::StringUtil::format("%04d", i);
        ui->comboBoxNum->addItem(num.c_str());
    }
}

void DialogProgram::appendProgram(const tv::Program& program)
{
    int rowCount = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(rowCount);
    setProgram(rowCount, program);
}


void DialogProgram::on_tableWidget_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous)
{
    if (!current)
    {
        return;
    }

    int row = current->row();
    showProgram(row);
}

void DialogProgram::showProgram(int row)
{
    if (row < 0 || row >= (int)m_programList.size())
    {
        return;
    }

    showProgram(m_programList[row]);
}

void DialogProgram::showProgram(const tv::Program& program)
{
    ui->comboBoxNum->setCurrentText(program.num.c_str());
    ui->lineEditName->setText(program.name.c_str());
    ui->textEditMemo->setPlainText(program.memo.c_str());
    ui->lineEditUrl->setText(program.url.c_str());
    ui->comboBoxFreqNum->setCurrentText(program.freqNum.c_str());
    ui->comboBoxFreqName->setCurrentText(program.freqName.c_str());
}

void DialogProgram::updateProgram(int row)
{
    if (row < 0 || row >= (int)m_programList.size())
    {
        return;
    }

    tv::Program& program = m_programList[row];
    program.num = ui->comboBoxNum->currentText().toStdString();
    program.name = ui->lineEditName->text().toStdString();
    program.memo = ui->textEditMemo->toPlainText().toStdString();
    program.url = ui->lineEditUrl->text().toStdString();
    program.freqNum = ui->comboBoxFreqNum->currentText().toStdString();
    program.freqName = ui->comboBoxFreqName->currentText().toStdString();

    setProgram(row, program);
}


void DialogProgram::refreshTable()
{
    ui->tableWidget->setRowCount(0);
    ui->tableWidget->clearContents();

    for (size_t i = 0; i < m_programList.size(); ++i)
    {
        const tv::Program& program = m_programList[i];

        appendProgram(program);
    }
}

void DialogProgram::fillFreqCombo()
{
    QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();
    ui->comboBoxFreqNum->setItemDelegate(itemDelegate);
    ui->comboBoxFreqNum->setStyleSheet("QComboBox QAbstractItemView::item {min-height: 28px;}");

    ui->comboBoxFreqName->setItemDelegate(itemDelegate);
    ui->comboBoxFreqName->setStyleSheet("QComboBox QAbstractItemView::item {min-height: 28px;}");




    for (size_t i = 0; i < m_freqList.size(); ++ i)
    {
        const tv::Frequence& freq = m_freqList[i];
        ui->comboBoxFreqNum->addItem(freq.num.c_str());

        ui->comboBoxFreqName->addItem(freq.name.c_str());
    }
}

void DialogProgram::on_comboBoxFreqNum_currentIndexChanged(int index)
{
    ui->comboBoxFreqName->setCurrentIndex(index);
}

void DialogProgram::on_comboBoxFreqName_currentIndexChanged(int index)
{
    ui->comboBoxFreqNum->setCurrentIndex(index);
}
